package com.lazydong.gui_gateway.gui;

import cn.hutool.core.util.StrUtil;
import com.lazydong.gui_gateway.GatewayApplication;
import com.lazydong.gui_gateway.gui.layout.HCustomLayout;
import com.lazydong.gui_gateway.gui.layout.VCustomLayout;
import com.lazydong.gui_gateway.model.ServiceIpAddr;
import com.lazydong.gui_gateway.model.ServiceRouteModel;
import com.lazydong.gui_gateway.route.RouteConfigFileUtil;
import com.lazydong.gui_gateway.route.RoutePropertyEnvironment;
import org.springframework.context.ApplicationEventPublisher;

import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;

/**
 * @author lazydong
 */
public class JFrameApp extends JFrame {
    public static String[] globalArgs = null;

    public static final AtomicReference<ApplicationEventPublisher> eventPublisher = new AtomicReference<>();
    public static AtomicInteger portDef = new AtomicInteger(44944);

    private static final int windowWidth = 600;
    private static final int windowHeight = 600;

    private static JComboBox<ServiceIpAddr> environmentBox;
    private static JTextField portJTextField;
    private static JButton startAppButton;

    public static JComboBox<ServiceIpAddr>[] jComboBoxes = new JComboBox[50];
    public static AtomicInteger jComboBoxesIndex = new AtomicInteger(0);


    ComboBoxItemListener comboBoxItemListener = new ComboBoxItemListener();

    public static void guiMain(String[] args) throws FileNotFoundException {
        globalArgs = args;
        JFrameApp app = new JFrameApp();
        RouteConfigFileUtil.initData();
        app.startApp();
    }

    private void startApp() {
        // 初始化窗口
        JFrame jFrame = new JFrame("这个是窗口的标题");
        // 设置窗口的位置和大小
        jFrame.setBounds(400, 300, windowWidth, windowHeight);
        Container contentPane = jFrame.getContentPane();
        contentPane.setLayout(new VCustomLayout());
        contentPane.setSize(windowWidth, windowHeight);
        addContentPaneLayout(contentPane);


        jFrame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                if (GatewayApplication.runFlag) {
                    JOptionPane.showMessageDialog(null, "先停止路由服务");
                    throw new RuntimeException("请先停止服务");
                }
            }
        });

        // 设置窗口是否可见
        jFrame.setVisible(true);
        // 设置窗口是否可以缩放
        jFrame.setResizable(false);
        /*
         * 设置窗口的相对位置。
         * 如果 comp 整个显示区域在屏幕内, 则将窗口放置到 comp 的中心;
         * 如果 comp 显示区域有部分不在屏幕内, 则将该窗口放置在最接近 comp 中心的一侧;
         * comp 为 null, 表示将窗口放置到屏幕中心。
         */
        jFrame.setLocationRelativeTo(null);
        /*
         * 设置窗口关闭按钮点击后的默认操作, 参考值:
         *     WindowConstants.DO_NOTHING_ON_CLOSE: 不执行任何操作。
         *     WindowConstants.HIDE_ON_CLOSE: 隐藏窗口（不会结束进程）, 再次调用 setVisible(true) 将再次显示。
         *     WindowConstants.DISPOSE_ON_CLOSE: 销毁窗口, 如果所有可显示的窗口都被 DISPOSE, 则可能会自动结束进程。
         *     WindowConstants.EXIT_ON_CLOSE: 退出进程。
         */
        jFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        jFrame.setLayout(null);
    }

    private void addContentPaneLayout(Container contentPane) {
        // 分两部分，上面环境选择和启动按钮
        JPanel oneLayout = new JPanel();
        oneLayout.setSize(contentPane.getWidth(), 100);
        addOneLayout(oneLayout);
        contentPane.add(oneLayout, "10%");

        // 下面tab页面做展示
        JPanel twoJPanel = new JPanel();
        twoJPanel.setSize(contentPane.getWidth(), windowHeight - 100);
        twoJPanel.setLayout(new HCustomLayout());
        addTwoLayout(twoJPanel);
        contentPane.add(twoJPanel, "90%");
    }

    private void addOneLayout(JPanel contentPane) {
        contentPane.setLayout(new HCustomLayout(HCustomLayout.Direction.Centre));
        JPanel temp1 = new JPanel();
        temp1.setSize(20, 30);
        contentPane.add(temp1);

        environmentBox = new JComboBox<>();
        for (ServiceIpAddr value : RouteConfigFileUtil.environmentMap.values()) {
            environmentBox.addItem(value);
        }
        environmentBox.setSize(100, 30);
        environmentBox.addItemListener(comboBoxItemListener);
        contentPane.add(environmentBox);

        JPanel temp2 = new JPanel();
        temp2.setSize(240, 30);
        contentPane.add(temp2);

        JLabel portJLabel = new JLabel("端口: ");
        portJLabel.setSize(40, 30);
        contentPane.add(portJLabel);

        portJTextField = new JTextField();
        portJTextField.setColumns(10);
        portJTextField.setText(String.valueOf(portDef.get()));
        portJTextField.addKeyListener(new KeyAdapter() {
            // 限制只能输入数字
            public void keyTyped(KeyEvent e) {
                String key = "0123456789";
                if (key.indexOf(e.getKeyChar()) < 0) {
                    e.consume();//如果不是数字则取消
                    return;
                }
                if (portJTextField.getText().length() > 4) {
                    e.consume();
                }
            }
        });
        portJTextField.setSize(60, 25);
        contentPane.add(portJTextField);

        JPanel temp3 = new JPanel();
        temp3.setSize(10, 30);
        contentPane.add(temp3);

        // 程序启动按钮
        startAppButton = new JButton();
        startAppButton.setText("启用路由");
        startAppButton.setSize(100, 30);
        startAppButton.setActionCommand("startRouteService");
        startAppButton.addActionListener(new ButtonListener());
        contentPane.add(startAppButton);
    }


    private void addTwoLayout(JPanel twoJPanel) {
        JTabbedPane jTabbedPane = new JTabbedPane(JTabbedPane.TOP, JTabbedPane.SCROLL_TAB_LAYOUT);

        JPanel jPanelSetting = new JPanel();
        jPanelSetting.setBackground(Color.green);
        jPanelSetting.setName("路由设置");
        fullSettingJPanel(jPanelSetting);

        //第一个参数：即选项卡显示的标题
        //第二个参数：即选项卡没张卡对应的面板
        jTabbedPane.add("路由设置", jPanelSetting);

        //设置默认的选项卡页，方式一：通过选项卡的索引
        jTabbedPane.setSelectedIndex(0);
//        //设置默认的选项卡页，方式二：通过选项卡变量名
//        jTabbedPane.setSelectedComponent(jPanelGreen);

        //为选项卡添加监听器
        jTabbedPane.addChangeListener(new JTabbedPaneChangeListener());
        jTabbedPane.setSize(twoJPanel.getWidth(), twoJPanel.getHeight());
        twoJPanel.add(jTabbedPane);
    }

    private void fullSettingJPanel(JPanel jPanelSetting) {
        jPanelSetting.setLayout(new HCustomLayout());

        // 左边的日志框
        JTextArea textArea = new JTextArea();
        textArea.setLineWrap(true);
        textArea.setEditable(false);
        JScrollPane scrollPane = new JScrollPane(textArea);
        jPanelSetting.add(scrollPane, "40%");
        LogUtil.logTextArea = textArea;

        // 右边的服务选项框
        JPanel serviceComboBox = new JPanel();
        serviceComboBox.setLayout(new VCustomLayout());
        jPanelSetting.add(serviceComboBox, "60%");
        for (ServiceRouteModel serviceRouteModel : RouteConfigFileUtil.serviceServiceRouteModelMap.values()) {
            JPanel boxJPanel = new JPanel();
            boxJPanel.setSize(300, 40);
            boxJPanel.setLayout(new HCustomLayout());

            JLabel jLabel = new JLabel(serviceRouteModel.getServiceName());
            jLabel.setSize(150, 40);
            boxJPanel.add(jLabel);

            JComboBox<ServiceIpAddr> box = new JComboBox<>();
            jComboBoxes[jComboBoxesIndex.getAndIncrement()] = box;
            box.setSize(150, 30);
            for (ServiceIpAddr value : serviceRouteModel.getList()) {
                box.addItem(value);
            }
            boxJPanel.add(box);
            box.addItemListener(comboBoxItemListener);
            serviceComboBox.add(boxJPanel);
        }


    }

    private void fullShowJPanel(JPanel jPanelRed) {


    }



    private void fullSettingJPanel1(JPanel jPanelSetting) {
        // jPanelSetting 水平布局，左边展示操作日志，右边操作按钮
        jPanelSetting.setBackground(Color.BLUE);
        jPanelSetting.setLayout(new HCustomLayout());

        JPanel zuo = new JPanel();
        zuo.setSize(30, jPanelSetting.getHeight());
        zuo.setBackground(Color.yellow);
        jPanelSetting.add(zuo, "60%");


//        JPanel you = new JPanel();
//        you.setLayout(new MyVFlowLayout());
//        you.setSize(30, jPanelSetting.getHeight());
//        you.setBackground(Color.yellow);
//        jPanelSetting.add(you, "40%");
//
//        for (ServiceRouteModel serviceRouteModel : RouteConfigFileUtil.serviceServiceRouteModelMap.values()) {
//            JPanel boxJPanel = new JPanel();
//            boxJPanel.setSize(300, 40);
//            boxJPanel.setLayout(new MyHFlowLayout());
//
//            JLabel jLabel = new JLabel(serviceRouteModel.getServiceName());
//            jLabel.setSize(150, 40);
//            boxJPanel.add(jLabel);
//
//            JComboBox<ServiceIpAddr> box = new JComboBox<>();
//            jComboBoxes[jComboBoxesIndex.getAndIncrement()] = box;
//            box.setSize(150, 30);
//            for (ServiceIpAddr value : serviceRouteModel.getList()) {
//                box.addItem(value);
//            }
//            boxJPanel.add(box);
//            box.addItemListener(comboBoxItemListener);
//            you.add(boxJPanel);
//        }


    }


    /**
     * 选项卡监听器
     */
    private static class JTabbedPaneChangeListener implements ChangeListener {
        @Override
        public void stateChanged(ChangeEvent e) {
            JTabbedPane jTabbedPane = (JTabbedPane) e.getSource();
            int selectedIndex = jTabbedPane.getSelectedIndex();
            System.out.println(selectedIndex);
        }
    }

    /**
     * 按钮监听器
     */
    private static class ButtonListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent event) {
            // 启动路由服务
            if ("startRouteService".equals(event.getActionCommand())) {
                ArrayList<ServiceIpAddr> serviceIpAddrList = new ArrayList<ServiceIpAddr>();
                ServiceIpAddr environmentSelectedItem = (ServiceIpAddr) environmentBox.getSelectedItem();
                if (environmentSelectedItem == null) {
                    JOptionPane.showMessageDialog(null, "环境配置异常");
                    throw new RuntimeException("环境配置异常");
                }
                serviceIpAddrList.add(environmentSelectedItem);

                for (JComboBox<ServiceIpAddr> jComboBox : jComboBoxes) {
                    if (jComboBox == null) {
                        continue;
                    }
                    ServiceIpAddr selectedItem = (ServiceIpAddr) jComboBox.getSelectedItem();
                    if (selectedItem == null || StrUtil.isBlank(selectedItem.getAddr())) {
                        continue;
                    }
                    serviceIpAddrList.add(selectedItem);
                    System.out.println(selectedItem.getServiceName() + " - " + selectedItem.getName());
                }
                String text = portJTextField.getText();
                portJTextField.setEditable(false);
                startAppButton.setEnabled(false);
                startAppButton.setText("停止路由");
                startAppButton.setActionCommand("stopRouteService");
                RoutePropertyEnvironment.port.set(Integer.parseInt(text));
                GatewayApplication.startGateway(globalArgs);
                eventPublisher.get().publishEvent(serviceIpAddrList);
                startAppButton.setEnabled(true);
                LogUtil.appendLog("路由服务已启动...");
            }
            // 停止路由服务
            if ("stopRouteService".equals(event.getActionCommand())) {
                startAppButton.setEnabled(false);
                GatewayApplication.stopGateway();
                startAppButton.setEnabled(true);
                portJTextField.setEditable(true);
                startAppButton.setText("启用路由");
                startAppButton.setActionCommand("startRouteService");
                LogUtil.appendLog("路由服务已停止...");
            }
        }
    }

    /**
     * 下拉框监听器
     */
    private static class ComboBoxItemListener implements ItemListener {
        @Override
        public void itemStateChanged(ItemEvent e) {
            if (ItemEvent.SELECTED != e.getStateChange()) {
                return;
            }
            ServiceIpAddr item = (ServiceIpAddr) e.getItem();
            ApplicationEventPublisher applicationEventPublisher = JFrameApp.eventPublisher.get();
            if (applicationEventPublisher != null && GatewayApplication.runFlag) {
                applicationEventPublisher.publishEvent(item);
            }
        }
    }
}
